package com.smsservice.servico;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.telephony.SmsManager;
import android.util.Log;
import android.widget.Toast;

import com.smsservice.R;
import com.smsservice.activities.Principal;
import com.smsservice.banco.ConexaoBD;
import com.smsservice.bean.SmsBean;

public class ServicoEnvioSms extends Service {

	// Constante com o nome das preferencias salvas
	public static final String PREFS_NAME = "ConfigServidorPref";

	String url;
	String dbName;
	String userName;
	String password;

	String enderecoIP;
	String porta;
	String nomeBaseDados;

	ResultSet rs = null;
	ConexaoBD conn = null;
	int limite;
	String sql;
	boolean continuar = true;
	boolean enviada = false;
	
	BroadcastReceiver receiver = null;

	private NotificationManager mNM;

	@Override
	public void onCreate() {
		mNM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

		// Display a notification about us starting. We put an icon in the status bar.
		showNotification("Serviço de SMS iniciado", false, 1);
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		Toast.makeText(this, "Serviço iniciado com sucesso!", Toast.LENGTH_SHORT).show();

		Thread t = new Thread() {
			public void run() {
				getConfiguracoes();
				try {
					conn = ConexaoBD.getDbCon(url, dbName, userName, password);

					limite = 1;

					while (continuar) {
						sql = "SELECT id, destino, mensagem, data, status from sms where status = '0' " + "limit " + String.valueOf(limite);
						Log.i("sms", "SQL> " + sql);
						rs = conn.query(sql);

						while (rs.next()) {
							SmsBean sms = new SmsBean();
							sms.setId(rs.getInt("id"));
							sms.setDestino(rs.getString("destino"));
							sms.setMensagem(rs.getString("mensagem"));
							sms.setData(rs.getDate("data"));
							sms.setStatus(rs.getString("status"));

							// envia sms
							sendSMS(sms.getDestino(), sms.getMensagem(), sms.getId());

							// atualiza status da mensagem para enviada = 1
							if (enviada){
								atualizaStatusSMS(conn, sms.getId());
								enviada = false;
							}
							Thread.sleep(2000);
						}
						
						Thread.sleep(5000);
					}

				} catch (SQLException e) {
					showNotification(e.getMessage().toString(), true, 2);
					// e.printStackTrace();
				} catch (InterruptedException e) {
					e.printStackTrace();

				} catch (ClassNotFoundException e) {
					System.err.println(".....Class com.mysql.jdbc.Driver not found!");
					showNotification(e.getMessage().toString(), true, 10);
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					System.err.println("Illegal access");
					showNotification(e.getMessage().toString(), true, 11);
					e.printStackTrace();
				} catch (InstantiationException e) {
					System.err.println("instantiation exc eption");
					showNotification(e.getMessage().toString(), true, 12);
					e.printStackTrace();
				}
			}
		};
		t.start();
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		// Cancel the persistent notification.
		mNM.cancelAll();
		continuar = false;
		
		if(receiver != null)
			unregisterReceiver(receiver);
	}

	/**
	 * Show a notification while this service is running.
	 */
	@SuppressWarnings("deprecation")
	private void showNotification(String text, boolean erro, int codigoNotificao) {

		// Set the icon, scrolling text and timestamp

		//Notification notification = new Notification(R.drawable.sms_icon, text, System.currentTimeMillis());
		
		NotificationCompat.Builder builder =  
		        new NotificationCompat.Builder(this)  
		        .setSmallIcon(R.drawable.sms_icon)  
		        .setContentTitle("Serviço de SMS.")  
		        .setContentText(text);  
		
		Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
		
		builder.setSound(alarmSound);
		

		Bundle parametros = new Bundle();
		parametros.putBoolean("erro", erro);
		parametros.putString("mensagem", text);
		parametros.putInt("codigoNotify", codigoNotificao);

		Intent iPrincipal = new Intent(this, Principal.class);
		iPrincipal.putExtras(parametros);

		PendingIntent contentIntent = PendingIntent.getActivity(this, 0, iPrincipal, PendingIntent.FLAG_UPDATE_CURRENT);

		builder.setContentIntent(contentIntent); 
		
		// Set the info for the views that show in the notification panel.
		//notification.setLatestEventInfo(this, "Serviço de SMS.", text, contentIntent);

		// Send the notification.
		// We use a string id because it is a unique number. We use it later to cancel.
		mNM.notify(codigoNotificao, builder.build());
	}

	private void getConfiguracoes() {
		// Restaura as preferencias gravadas
		SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
		enderecoIP = settings.getString("EnderecoIP", "");
		porta = String.valueOf(settings.getString("Porta", ""));

		// Monta a URL do banco
		url = "jdbc:mysql://" + enderecoIP + ":" + porta + "/";

		dbName = settings.getString("NomeBaseDados", "");
		userName = settings.getString("nomeUsuario", "");
		password = settings.getString("Senha", "");

		Log.i("SMS", "Url conexao: " + url);
	}

	public void atualizaStatusSMS(ConexaoBD conn, long idSMS) {
		try {
			// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
			// String dataAtual = sdf.format(new Date());
			String dataAtual = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
			String sql = "UPDATE sms SET status = '1', data = '" + dataAtual + "' WHERE id = " + String.valueOf(idSMS);
			Log.i("sms", "Atualizando status de sms enviada: " + sql);
			conn.insert(sql);
			
		} catch (SQLException e) {
			showNotification("Erro na atualização da tabela sms.", true, 4);
			e.printStackTrace();
		}
	}

	// ---sends an SMS message to another device---
	private void sendSMS(String phoneNumber, String message, long idSms) {
		String SENT = "SMS_SENT";
		// String DELIVERED = "SMS_DELIVERED";

		Intent iSmsEnviada = new Intent(SENT);
		iSmsEnviada.putExtra("idSms", idSms);

		PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, iSmsEnviada, 0);

		// PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);

		// ---when the SMS has been sent---
		registerReceiver(receiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context arg0, Intent data) {			

				switch (getResultCode()) {
				case Activity.RESULT_OK:
					enviada = true;
					Toast.makeText(getBaseContext(), "SMS Enviada", Toast.LENGTH_SHORT).show();					
					break;
				case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
					showNotification("Falha genérica.", true, 5);
					Toast.makeText(getBaseContext(), "Falha generica", Toast.LENGTH_SHORT).show();
					break;
				case SmsManager.RESULT_ERROR_NO_SERVICE:
					showNotification("Sem serviço.", true, 6);
					Toast.makeText(getBaseContext(), "Sem serviço", Toast.LENGTH_SHORT).show();
					break;
				case SmsManager.RESULT_ERROR_NULL_PDU:
					showNotification("NULL PDU", true, 7);
					Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
					break;
				case SmsManager.RESULT_ERROR_RADIO_OFF:
					showNotification("Radio OFF", true, 8);
					Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
					break;
				}
			}
		}, new IntentFilter(SENT));

		// // ---when the SMS has been delivered---
		// registerReceiver(new BroadcastReceiver() {
		// @Override
		// public void onReceive(Context arg0, Intent arg1) {
		// switch (getResultCode()) {
		// case Activity.RESULT_OK:
		// Toast.makeText(getBaseContext(), "SMS entregue", Toast.LENGTH_SHORT).show();
		// break;
		// case Activity.RESULT_CANCELED:
		// showNotification("SMS não entregue: Cancelada", true, 9);
		// Toast.makeText(getBaseContext(), "SMS não entregue", Toast.LENGTH_SHORT).show();
		// break;
		// }
		// }
		// }, new IntentFilter(DELIVERED));

		SmsManager sms = SmsManager.getDefault();
		sms.sendTextMessage(phoneNumber, null, message, sentPI, null);
	}

}
